#!/bin/bash

# debug
# set -x

NVIM_HOME=$HOME/.nvim
OS="$(uname -s)"

# utils {

info() {
	local content="$*"
	printf "[lin.nvim] - %s\n" "$content"
}

err() {
	local content="$*"
	info "error! $content"
}

skip_info() {
	local old="$IFS"
	IFS='/'
	local target="'$*'"
	info "$target already exist, skip..."
	IFS=$old
}

backup() {
	local src=$1
	if [[ -f "$src" || -d "$src" ]]; then
		local target=$src.$(date +"%Y-%m-%d.%H-%M-%S")
		info "backup '$src' to '$target'"
		mv $src $target
	fi
}

install() {
	local command="$1"
	local target="$2"
	if ! type "$target" >/dev/null 2>&1; then
		info "install '$target' with command: '$command'"
		eval "$command"
	else
		skip_info $target
	fi
}

latest_github_release_tag() {
	local org="$1"
	local repo="$2"
	local uri="https://github.com/$org/$repo/releases/latest"
	curl -s -f -L $uri | grep "href=\"/$org/$repo/releases/tag" | grep -Eo 'href="/[a-zA-Z0-9#~.*,/!?=+&_%:-]*"' | head -n 1 | cut -d '"' -f2 | cut -d "/" -f6
}

# utils }

# apt: ubuntu/debian {

apt_install_neovim() {
	sudo snap install nvim --classic
}

apt_install_nodejs() {
	# see: https://github.com/nodesource/distributions
	info "install nodejs-lts from NodeSource"
	sudo apt-get -qq -y install curl
	curl -fsSL https://deb.nodesource.com/setup_lts.x -o nodesource_setup.sh
	sudo -E bash nodesource_setup.sh
	sudo apt-get -qq update
	sudo apt-get -qq -y install nodejs
}

apt_install_git() {
	sudo apt-add-repository ppa:git-core/ppa
	sudo apt-get -qq update
	sudo apt-get -qq -y install git
}

apt_install_go() {
	git clone --depth=1 https://github.com/kerolloz/go-installer
	export GOROOT="$HOME/.go" # where go is installed
	export GOPATH="$HOME/go"  # user workspace
	bash ./go-installer/go.sh
	export PATH="$PATH:$GOROOT/bin"
	export PATH="$PATH:$GOPATH/bin"
}

apt_install_lazygit() {
	go install github.com/jesseduffield/lazygit@latest
}

apt_install_fzf() {
	go install github.com/junegunn/fzf@latest
}

apt_deps() {
	info "apt install dependencies"
	sudo locale-gen en_US
	sudo locale-gen en_US.UTF-8
	sudo update-locale

	# neovim
	install "apt_install_neovim" "nvim"

	# c++ toolchain
	install "sudo apt-get -qq -y install build-essential" "gcc"
	install "sudo apt-get -qq -y install build-essential" "make"
	install "sudo apt-get -qq -y install autoconf" "autoconf"
	install "sudo apt-get -qq -y install automake" "automake"
	install "sudo apt-get -qq -y install pkg-config" "pkg-config"
	install "sudo apt-get -qq -y install cmake" "cmake"
	install "apt_install_go" "go"

	# download tools
	install "apt_install_git" "git"
	install "sudo apt-get -qq -y install curl" "curl"
	install "sudo apt-get -qq -y install wget" "wget"

	# compress tools
	install "sudo apt-get -qq -y install p7zip" "7z"
	install "sudo apt-get -qq -y install gzip" "gzip"
	install "sudo apt-get -qq -y install unzip" "unzip"

	# copy/paste tools
	install "sudo apt-get -qq -y install xsel" "xsel"
	install "sudo apt-get -qq -y install xclip" "xclip"

	# python3
	install "sudo apt-get -qq -y install python3 python3-dev python3-venv python3-pip python3-docutils" "python3"
	install "sudo apt-get -qq -y install python3 python3-dev python3-venv python3-pip python3-docutils" "pip3"

	# nodejs
	install "apt_install_nodejs" "node"

	# dev tools
	install "apt_install_lazygit" "lazygit"
	install "apt_install_fzf" "fzf"
}

# }

# dnf: fedora/centos {

dnf_install_lazygit() {
	sudo dnf copr enable atim/lazygit -y
	sudo dnf install lazygit
}

dnf_deps() {
	info "dnf install dependencies"
	sudo dnf check-update

	# neovim
	install "sudo dnf install -y neovim" "nvim"

	# c++ toolchain
	install "sudo dnf group install -y \"Development Tools\"" "gcc"
	install "sudo dnf group install -y \"Development Tools\"" "make"
	install "sudo dnf install -y autoconf" "autoconf"
	install "sudo dnf install -y automake" "automake"
	install "sudo dnf install -y pkg-config" "pkg-config"
	install "sudo dnf install -y cmake" "cmake"
	install "sudo dnf install -y golang" "go"

	# download tools
	install "sudo dnf install -y git" "git"
	install "sudo dnf install -y curl" "curl"
	install "sudo dnf install -y wget" "wget"

	# compress tools
	install "sudo dnf install -y gzip" "gzip"
	install "sudo dnf install -y p7zip" "7z"
	install "sudo dnf install -y unzip" "unzip"

	# # luarocks
	# install "sudo dnf install -y luarocks" "luarocks"

	# copy/paste tools
	install "sudo dnf install -y xsel" "xsel"
	install "sudo dnf install -y xclip" "xclip"

	# python3
	install "sudo dnf install -y python3 python3-devel python3-pip python3-docutils" "python3"
	install "sudo dnf install -y python3 python3-devel python3-pip python3-docutils" "pip3"

	# nodejs
	install "sudo dnf install -y nodejs npm" "node"

	# dev tools
	install "dnf_install_lazygit" "lazygit"
	install "sudo dnf install -y fzf" "fzf"
}

# }

# packman: manjaro/archlinux {

pacman_deps() {
	info "pacman install dependencies"
	sudo pacman -Syy

	# neovim
	install "yes | sudo pacman -S neovim" "nvim"

	# c++ toolchain
	install "yes | sudo pacman -S base-devel" "gcc"
	install "yes | sudo pacman -S base-devel" "make"
	install "yes | sudo pacman -S autoconf" "autoconf"
	install "yes | sudo pacman -S automake" "automake"
	install "yes | sudo pacman -S pkg-config" "pkg-config"
	install "yes | sudo pacman -S cmake" "cmake"
	install "yes | sudo pacman -S go" "go"

	# download tools
	install "yes | sudo pacman -S git" "git"
	install "yes | sudo pacman -S curl" "curl"
	install "yes | sudo pacman -S wget" "wget"

	# compress tools
	install "yes | sudo pacman -S gzip" "gzip"
	install "yes | sudo pacman -S p7zip" "7z"
	install "yes | sudo pacman -S unzip" "unzip"

	# copy/paste tools
	install "yes | sudo pacman -S xsel" "xsel"
	install "yes | sudo pacman -S xclip" "xclip"

	# python3
	install "yes | sudo pacman -S python python-pip" "python3"
	install "yes | sudo pacman -S python python-pip" "pip3"

	# node
	install "yes | sudo pacman -S nodejs npm" "node"

	# dev tools
	install "yes | sudo pacman -S lazygit" "lazygit"
	install "yes | sudo pacman -S fzf" "fzf"
}

# }

# homebrew: macos {

brew_deps() {
	info "brew install dependencies"

	if ! type clang >/dev/null 2>&1; then
		xcode-select --install
	fi
	if ! type brew >/dev/null 2>&1; then
		/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
	fi

	brew update

	# neovim
	install "brew install neovim" "nvim"

	# c++ toolchain
	install "brew install cmake" "cmake"
	install "brew install pkg-config" "pkg-config"
	install "brew install go" "go"

	# download tools
	install "brew install git" "git"
	install "brew install curl" "curl"
	install "brew install wget" "wget"

	# compress tools
	install "brew install gzip" "gzip"
	install "brew install p7zip" "7z"
	install "brew install unzip" "unzip"

	# python3
	install "brew install python3" "python3"

	# nodejs
	install "brew install node" "node"

	# dev tools
	install "brew install jesseduffield/lazygit/lazygit" "lazygit"
	install "brew install fzf" "fzf"
}

# }

# dependency

rust_deps() {
	info "install rust and modern commands"
	install "curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y" "cargo"
	install "curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y" "rustc"
	if [ -f $HOME/.cargo/env ]; then
		. "$HOME/.cargo/env"
	fi
	install "cargo install fd-find" "fd"
	install "cargo install ripgrep" "rg"
	install "cargo install --locked bat" "bat"
	install "cargo install eza" "eza"
}

npm_deps() {
	info "npm install packages"
	install "sudo npm install --silent -g trash-cli" "trash"
}

github_install_nerdfont() {
	if [ "$OS" = "Darwin" ]; then
		local font_name=$2
		info "install $font_name nerd fonts with brew"
		brew install $font_name
	else
		mkdir -p ~/.local/share/fonts && cd ~/.local/share/fonts
		local org="ryanoasis"
		local repo="nerd-fonts"
		local font_file=$1
		local font_version=$(latest_github_release_tag $org $repo)
		local font_url="https://github.com/$org/$repo/releases/download/$font_version/$font_file"
		info "install $font_file($font_version) nerd fonts from github"
		if [ -f $font_file ]; then
			rm -rf $font_file
		fi
		curl -s -L $font_url -o $font_file
		if [ $? -ne 0 ]; then
			info "failed to download $font_file, skip..."
		else
			unzip -q -o $font_file
			info "install $font_file($font_version) nerd font from github - done"
		fi
		sudo fc-cache -f
	fi
}

font_deps() {
	github_install_nerdfont "Hack.zip" "font-hack-nerd-font"
	info "please set 'Hack NFM' (or 'Hack Nerd Font Mono') as your terminal font"
}

nvim_config() {
	info "install ~/.config/nvim/init.lua for neovim"
	mkdir -p $HOME/.config
	backup $HOME/.config/nvim
	ln -s $NVIM_HOME $HOME/.config/nvim

	# # nvim-treesitter
	# local nvim_treesitter_home="$NVIM_HOME/lua/configs/nvim-treesitter/nvim-treesitter"
	# local nvim_treesitter_ensure_installed="$nvim_treesitter_home/ensure_installed.lua"
	# if [ ! -f $nvim_treesitter_ensure_installed ]; then
	#     cp $nvim_treesitter_home/ensure_installed_sample.lua $nvim_treesitter_ensure_installed
	# fi

	# nvim-lspconfig
	local nvim_lspconfig_home="$NVIM_HOME/lua/configs/neovim/nvim-lspconfig"
	local nvim_lspconfig_setup_handlers="$nvim_lspconfig_home/setup_handlers.lua"
	if [ ! -f $nvim_lspconfig_setup_handlers ]; then
		cp $nvim_lspconfig_home/setup_handlers_sample.lua $nvim_lspconfig_setup_handlers
	fi

	# mason-lspconfig.nvim
	local mason_lspconfig_home="$NVIM_HOME/lua/configs/williamboman/mason-lspconfig-nvim"
	local mason_lspconfig_ensure_installed="$mason_lspconfig_home/ensure_installed.lua"
	if [ ! -f $mason_lspconfig_ensure_installed ]; then
		cp $mason_lspconfig_home/ensure_installed_sample.lua $mason_lspconfig_ensure_installed
	fi
	local mason_lspconfig_setup_handlers="$mason_lspconfig_home/setup_handlers.lua"
	if [ ! -f $mason_lspconfig_setup_handlers ]; then
		cp $mason_lspconfig_home/setup_handlers_sample.lua $mason_lspconfig_setup_handlers
	fi

	# mason-null-ls.nvim
	local mason_null_ls_home="$NVIM_HOME/lua/configs/jay-babu/mason-null-ls-nvim"
	local mason_null_ls_ensure_installed="$mason_null_ls_home/ensure_installed.lua"
	if [ ! -f $mason_null_ls_ensure_installed ]; then
		cp $mason_null_ls_home/ensure_installed_sample.lua $mason_null_ls_ensure_installed
	fi
	local mason_null_ls_setup_handlers="$mason_null_ls_home/setup_handlers.lua"
	if [ ! -f $mason_null_ls_setup_handlers ]; then
		cp $mason_null_ls_home/setup_handlers_sample.lua $mason_null_ls_setup_handlers
	fi

	# conform.nvim
	local conform_home="$NVIM_HOME/lua/configs/stevearc/conform-nvim"
	local conform_formatters_by_ft="$conform_home/formatters_by_ft.lua"
	if [ ! -f $conform_formatters_by_ft ]; then
		cp $conform_home/formatters_by_ft_sample.lua $conform_formatters_by_ft
	fi

	# # nvim-lint
	# local nvim_lint_home="$NVIM_HOME/lua/configs/mfussenegger/nvim-lint"
	# local nvim_lint_linters_by_ft="$nvim_lint_home/linters_by_ft.lua"
	# if [ ! -f $nvim_lint_linters_by_ft ]; then
	#     cp $nvim_lint_home/linters_by_ft_sample.lua $nvim_lint_linters_by_ft
	# fi
}

info "install for $OS"

# dependency
case "$OS" in
Linux)
	if [ -f "/etc/arch-release" ] || [ -f "/etc/artix-release" ]; then
		pacman_deps
	elif [ -f "/etc/fedora-release" ] || [ -f "/etc/redhat-release" ]; then
		dnf_deps
	elif [ -f "/etc/gentoo-release" ]; then
		info "gentoo ($OS) is not supported, exit..."
		exit 1
	else
		# otherwise, assume it is apt
		apt_deps
	fi
	;;
Darwin)
	brew_deps
	;;
FreeBSD | NetBSD | OpenBSD)
	info "$OS is not supported, exit..."
	exit 1
	;;
*)
	info "$OS is not supported, exit..."
	exit 1
	;;
esac

rust_deps
npm_deps
font_deps
nvim_config

info "install for $OS - done"
